#include <behaviortree_cpp_v3/behavior_tree.h>
#include <behaviortree_cpp_v3/bt_factory.h>
#include <behaviortree_cpp_v3/crossdoor_nodes.h>
#include <behaviortree_cpp_v3/loggers/bt_cout_logger.h>
#include <behaviortree_cpp_v3/loggers/bt_minitrace_logger.h>
#include <behaviortree_cpp_v3/loggers/bt_file_logger.h>
#include <behaviortree_cpp_v3/loggers/bt_zmq_publisher.h>
using namespace std;

static const char* xml_text = R"(
<root main_tree_to_execute = "MainTree">
	<!--------------------------------------->
    <BehaviorTree ID="DoorClosed">
        <Sequence name="door_closed_sequence">
            <Inverter>
                <Condition ID="IsDoorOpen"/>
            </Inverter>
            <RetryUntilSuccessful num_attempts="4">
                <OpenDoor/>
            </RetryUntilSuccessful>
            <PassThroughDoor/>
        </Sequence>
    </BehaviorTree>
    <!--------------------------------------->
    <BehaviorTree ID="MainTree">
        <Sequence>
            <Fallback name="root_Fallback">
                <Sequence name="door_open_sequence">
                    <IsDoorOpen/>
                    <PassThroughDoor/>
                </Sequence>
                <SubTree ID="DoorClosed"/>
                <PassThroughWindow/>
            </Fallback>
            <CloseDoor/>
        </Sequence>
    </BehaviorTree>
    <!---------------------------------------> 
</root>
 )";

int main(int argc, char** argv)
{
    BT::BehaviorTreeFactory factory;
    CrossDoor::RegisterNodes(factory);
    auto tree = factory.createTreeFromText(xml_text);

    StdCoutLogger logger_cout(tree);
    FileLogger logger_file(tree, "bt_trace.fbl");
    // MinitraceLogger logger_minitrace(tree, "bt_trace.json");
    PublisherZMQ publisher_zmq(tree);
    // BT::Groot2Publisher publisher(tree);

    printTreeRecursively(tree.rootNode());
    NodeStatus status;
    for (int i = 0; i < 10; i++)
    {
        cout << "tick: " << i << "--------------------------------" << endl;
        status = tree.tickRoot();
        cout << "tick status: " << status << endl;
        tree.sleep(std::chrono::seconds(1));
    }

    return 0;
}